class LDay {
  static final List<List<int> Function(String)> _hooks = [
    _parseCNUnit,
    _parseCN
  ];

  late DateTime _date;
  LDay(
      {int? year,
      int? month,
      int? day,
      int? hour,
      int? minute,
      int? second,
      int? millsecond,
      int? microsecound,
      bool utc = false}) {
    var now = DateTime.now();
    _date = _createTime(
        year ?? now.year,
        month ?? now.month,
        day ?? now.day,
        hour ?? now.hour,
        minute ?? now.minute,
        second ?? now.second,
        millsecond ?? now.microsecond,
        microsecound ?? now.microsecond,
        utc);
  }

  /// 转换成系统时间对象
  DateTime toDateTime() {
    return _date;
  }

  /// 获取年
  int get year {
    return _date.year;
  }

  /// 设置年
  set year(int y) {
    _date = _createTime(y, month, day, hour, minute, second, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取月
  int get month {
    return _date.month;
  }

  /// 设置月
  set month(int m) {
    _date = _createTime(year, m, day, hour, minute, second, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取月中文
  String get monthZh {
    return _monthDayZh[_date.month]!;
  }

  /// 获取日
  int get day {
    return _date.day;
  }

  /// 设置日
  set day(int d) {
    _date = _createTime(year, month, d, hour, minute, second, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取本月总天数
  int get days {
    return LDay.monthDays(year, month);
  }

  /// 获取日中文
  String get dayZh {
    return _dayZh[_date.day]!;
  }

  /// 获取时
  int get hour {
    return _date.hour;
  }

  /// 设置时
  set hour(int h) {
    _date = _createTime(year, month, day, h, minute, second, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取分
  int get minute {
    return _date.minute;
  }

  /// 设置分
  set minute(int m) {
    _date = _createTime(year, month, day, hour, m, second, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取秒
  int get second {
    return _date.second;
  }

  /// 设置秒
  set second(int s) {
    _date = _createTime(year, month, day, hour, minute, s, millisecond,
        microsecond, _date.isUtc);
  }

  /// 获取毫秒
  int get millisecond {
    return _date.millisecond;
  }

  /// 设置毫秒
  set millisecond(int ms) {
    _date = _createTime(
        year, month, day, hour, minute, second, ms, microsecond, _date.isUtc);
  }

  /// 获取微秒
  int get microsecond {
    return _date.microsecond;
  }

  /// 设置微秒
  set microsecond(int us) {
    _date = _createTime(
        year, month, day, hour, minute, second, millisecond, us, _date.isUtc);
  }

  /// 获取星期
  int get weekday {
    return _date.weekday;
  }

  /// 获取星期中文
  String get weekdayZh {
    return _weekDayZh[_date.weekday]!;
  }

  /// 获取毫秒时间戳
  int get unix {
    return _date.millisecondsSinceEpoch;
  }

  /// 获取微秒时间戳
  int get microUnix {
    return _date.microsecondsSinceEpoch;
  }

  /// 是否utc时间
  bool get isUtc {
    return _date.isUtc;
  }

  /// 是否闰年
  bool get isLeapYear {
    return leapYear(year);
  }

  /// 根据时间对象创建一个新时间
  static LDay fromLDay(LDay day) {
    return LDay(
        year: day.year,
        month: day.month,
        day: day.day,
        hour: day.hour,
        minute: day.minute,
        second: day.second,
        millsecond: day.millisecond,
        microsecound: day.microsecond,
        utc: day.isUtc);
  }

  /// 根据系统时间创建一个新时间
  static LDay fromDateTime(DateTime date) {
    return LDay(
        year: date.year,
        month: date.month,
        day: date.day,
        hour: date.hour,
        minute: date.minute,
        second: date.second,
        millsecond: date.millisecond,
        microsecound: date.microsecond,
        utc: date.isUtc);
  }

  /// 添加时间解析钩子 可以在解析时间时进行自定义解析
  ///
  /// 返回int数组,[0:年,1:月,2:日,3:时,4:分,5:秒,6:毫秒,7:微秒]
  ///
  /// 长度不限,如果长度不够则自动补 0,长度超出则忽略
  ///
  /// `无法解析时请抛出异常,将使用下一个钩子进行解析`
  static void addParseHooks(List<int> Function(String) hook) {
    _hooks.add(hook);
  }

  /// 根据字符串创建一个新时间
  ///
  /// 如果有特殊格式,需要自己解析,请在解析前使用[`addParseHooks`] 添加解析钩子
  ///
  ///可接受字符串的示例：
  ///
  /// * `"二零二四年三月二十八日 十二点十二分十二秒十二毫秒十二微秒"`
  /// * `"二零二四年三月二十八日 十二时十二分十二秒"`
  /// * `"二零二四年三月二十八日 十二点十二分"`
  /// * `"二零二四年三月二十八日 十二点"`
  /// * `"二零二四年"`
  /// * `"二零二四年三月"`
  /// * `"二零二四年三月二十八日"`
  /// * `"2021年12月31日 12点12分12秒12毫秒12微秒"`
  /// * `"2021年12月31日 12时12分12秒12毫秒12微秒"`
  /// * `"2021年12月31日 12时12分12秒"`
  /// * `"2021年12月31日12时12分12秒"`
  /// * `"2021年12月31日 12时"`
  /// * `"2021年"`
  /// * `"2012/02/27"`
  /// * `"2012/02/27 13:27:00"`
  /// * `"2012-02-27"`
  /// * `"2012-02-27 13:27:00"`
  /// * `“2012-02-27 13:27:00.123456789z”`
  /// * `“2012-02-27 13:27:00123456789z”`
  /// * `"20120227 13:27:00"`
  /// * `“20120227T132700”`
  /// * `"20120227"`
  /// * `"+20120227"`
  /// * `“2012-02-27T14Z”`
  /// * `“2012-02-27T14+00:00”`
  /// * `“-123450101 00:00:00 Z”`：在-12345。
  /// * `“2002-02-27T14:00:00-0500”`：与`“2002.02-27T19:00:00Z”相同`
  ///
  ///此方法接受超出范围的单位值并解释
  ///它们溢出到下一个较大的单位中。
  ///例如，“2020-01-42”将被解析为2020-02-11，因为
  ///该月的最后一个有效日期是2020-01-31，因此42天是
  ///解释为当月的31天加上下个月的11天。
  static LDay fromString(String date) {
    var nStr = date.replaceAll('/', '-');
    DateTime? t = DateTime.tryParse(nStr);

    List<int> res = [];
    if (t == null && _hooks.isNotEmpty) {
      for (var i = 0; i < _hooks.length; i++) {
        try {
          res = _hooks[i](date);
          break;
        } catch (e) {
          continue;
        }
      }
    }
    if (res.isEmpty) {
      t ??= DateTime.now();
    } else {
      List<int> res1 = [];
      for (var i = 0; i < 8; i++) {
        if (res.length > i) {
          res1.add(res[i]);
        } else {
          res1.add(0);
        }
      }
      t = DateTime(res1[0], res1[1], res1[2], res1[3], res1[4], res1[5],
          res1[6], res1[7]);
    }

    return LDay.fromDateTime(t);
  }

  /// 获取最小时间
  static LDay min(LDay a, LDay b) {
    return a.microUnix < b.microUnix ? a : b;
  }

  /// 获取最大时间
  static LDay max(LDay a, LDay b) {
    return a.microUnix > b.microUnix ? a : b;
  }

  /// 是否闰年
  static bool leapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  }

  /// 获取某一年的某个月的总天数
  static int monthDays(int y, int m) {
    if (m == 2) {
      if (LDay.leapYear(y)) {
        return 29;
      } else {
        return 28;
      }
    } else if ([1, 3, 5, 7, 8, 10, 12].contains(m)) {
      return 31;
    } else {
      return 30;
    }
  }

  /// 时间加法
  ///
  /// 超出的时间会往前进位
  ///
  /// ```dart
  /// LDay a = LDay(); // 2024-01-01 00:00:00.000000
  /// a.add(Duration(hours: 25)); // 增加25小时后,天位加1,小时位加1
  /// print(a); // 2024-01-02 01:00:00.000000
  /// ```
  LDay add(Duration time) {
    _date = DateTime.fromMicrosecondsSinceEpoch(
        _date.microsecondsSinceEpoch + time.inMicroseconds);
    return this;
  }

  /// 时间减法
  ///
  /// 超出的时间会往前借位
  ///
  /// ```dart
  /// LDay a = LDay(); // 2024-01-02 01:00:00.000000
  /// a.subtract(Duration(hours: 25)); // 减少25小时后,天位减1,小时位减1
  /// print(a); // 2024-01-01 00:00:00.000000
  /// ```
  LDay subtract(Duration time) {
    _date = DateTime.fromMicrosecondsSinceEpoch(
        _date.microsecondsSinceEpoch - time.inMicroseconds);
    return this;
  }

  /// 修改为某单位的开始时间
  ///
  /// 会改变本时间
  ///
  /// 返回自身
  LDay startOf(DayUnit unit) {
    switch (unit) {
      case DayUnit.year:
        _date = _createTime(year, 1, 1, 0, 0, 0, 0, 0, _date.isUtc);
        break;
      case DayUnit.month:
        _date = _createTime(year, month, 1, 0, 0, 0, 0, 0, _date.isUtc);
        break;
      case DayUnit.day:
        _date = _createTime(year, month, day, 0, 0, 0, 0, 0, _date.isUtc);
        break;
      case DayUnit.hour:
        _date = _createTime(year, month, day, hour, 0, 0, 0, 0, _date.isUtc);
        break;
      case DayUnit.minute:
        _date =
            _createTime(year, month, day, hour, minute, 0, 0, 0, _date.isUtc);
        break;
      case DayUnit.second:
        _date = _createTime(
            year, month, day, hour, minute, second, 0, 0, _date.isUtc);
        break;
      case DayUnit.millisecond:
        _date = _createTime(year, month, day, hour, minute, second, millisecond,
            0, _date.isUtc);
        break;
      case DayUnit.microsecond:
        _date = _createTime(year, month, day, hour, minute, second, millisecond,
            microsecond, _date.isUtc);
        break;
    }
    return this;
  }

  /// 修改为结束时间
  ///
  /// 会改变本时间
  ///
  /// 返回自身
  LDay endOf(DayUnit unit) {
    switch (unit) {
      case DayUnit.year:
        _date = _createTime(year, 12, 31, 23, 59, 59, 999, 999, _date.isUtc);
        break;
      case DayUnit.month:
        _date = _createTime(year, month, year % 4 > 0 ? 28 : 29, 23, 59, 59,
            999, 999, _date.isUtc);
        break;
      case DayUnit.day:
        _date =
            _createTime(year, month, day, 23, 59, 59, 999, 999, _date.isUtc);
        break;
      case DayUnit.hour:
        _date =
            _createTime(year, month, day, hour, 59, 59, 999, 999, _date.isUtc);
        break;
      case DayUnit.minute:
        _date = _createTime(
            year, month, day, hour, minute, 59, 999, 999, _date.isUtc);
        break;
      case DayUnit.second:
        _date = _createTime(
            year, month, day, hour, minute, second, 999, 999, _date.isUtc);
        break;
      case DayUnit.millisecond:
        _date = _createTime(year, month, day, hour, minute, second, millisecond,
            999, _date.isUtc);
        break;
      case DayUnit.microsecond:
        _date = _createTime(year, month, day, hour, minute, second, millisecond,
            microsecond, _date.isUtc);
        break;
    }
    return this;
  }

  /// 格式化
  /// - Y  年 显示2位 24
  /// - YY 年 显示2位 24
  /// - YYY 年 显示3位 2024
  /// - YYYY 年 显示4位 2024
  /// - YYYYY 年 显示中文5位 二零二四年
  /// - M 月 显示1位 1
  /// - MM 月 显示2位 01
  /// - MMM 月 显示中文2位 一月
  /// - D 日 显示1位 1
  /// - DD 日 显示2位 01
  /// - DDD 日 显示中文2位 一日
  /// - H 时 显示1位 1  24小时制
  /// - HH 时 显示2位 01  24小时制
  /// - HHH 时 显示中文2位 一点  24小时制
  /// - h 时 显示1位 1  12小时制
  /// - hh 时 显示2位 01  12小时制
  /// - hhh 时 显示中文2位 一点  12小时制
  /// - m 分 显示1位 1
  /// - mm 分 显示2位 01
  /// - mmm 分 显示中文2位 一分
  /// - s 秒 显示1位 1
  /// - ss 秒 显示2位 01
  /// - sss 秒 显示3位 一秒
  /// - SSS 毫秒 显示3位 001
  /// - SWS 微秒 显示3位 001
  /// - W 周 显示中文3位 星期一
  String format([String format = 'YYYY-MM-DD HH:mm:ss']) {
    const dayDartRegexpFormat =
        r'Y{1,5}|M{1,3}|D{1,3}|H{1,3}|h{1,3}|m{1,3}|s{1,3}|SSS|SWS|W';
    return format.replaceAllMapped(
        RegExp(dayDartRegexpFormat), (Match m) => _processMatchFromFormat(m));
  }

  /// 获取时间差 \
  /// 获取月份或年份差时可以设置月类型 按每个月30天或每个月31天或按自然月计算 \
  /// 返回整数差
  int diff(LDay day, DayUnit unit,
      [MonthType monthType = MonthType.useNaturalMonth]) {
    var d = day.microUnix - microUnix;
    var duration = Duration(microseconds: d);
    switch (unit) {
      case DayUnit.microsecond:
        return duration.inMicroseconds;
      case DayUnit.millisecond:
        return duration.inMilliseconds;
      case DayUnit.second:
        return duration.inSeconds;
      case DayUnit.minute:
        return duration.inMinutes;
      case DayUnit.hour:
        return duration.inHours;
      case DayUnit.day:
        return duration.inDays;
      case DayUnit.month:
        if (monthType == MonthType.use30) {
          return duration.inDays ~/ 30;
        } else if (monthType == MonthType.use31) {
          return duration.inDays ~/ 31;
        } else {
          var totalMonth = 0;
          var minDay = LDay.min(this, day);
          var maxDay = LDay.max(this, day);
          for (var i = minDay.year; i <= maxDay.year; i++) {
            for (var j = 1; j <= 12; j++) {
              if (i == minDay.year && j <= minDay.month ||
                  i == maxDay.year && j >= maxDay.month) {
                continue;
              } else {
                totalMonth++;
              }
            }
          }
          var maxDayToMinDayYear = LDay(
              year: minDay.year,
              month: maxDay.month,
              day: maxDay.day,
              hour: maxDay.hour,
              minute: maxDay.minute,
              second: maxDay.second,
              millsecond: maxDay.millisecond,
              microsecound: maxDay.microsecond);
          if (maxDayToMinDayYear.microUnix >= minDay.microUnix) {
            totalMonth++;
          }
          return totalMonth;
        }
      case DayUnit.year:
        if (monthType == MonthType.use30) {
          return duration.inDays / 30 ~/ 12;
        } else if (monthType == MonthType.use31) {
          return duration.inDays / 31 ~/ 12;
        } else {
          var minDay = LDay.min(this, day);
          var maxDay = LDay.max(this, day);
          var totalYear = maxDay.year - minDay.year - 1;
          var maxDayToMinDayYear = LDay(
              year: minDay.year,
              month: maxDay.month,
              day: maxDay.day,
              hour: maxDay.hour,
              minute: maxDay.minute,
              second: maxDay.second,
              millsecond: maxDay.millisecond,
              microsecound: maxDay.microsecond);
          if (maxDayToMinDayYear.microUnix >= minDay.microUnix) {
            totalYear++;
          }
          return totalYear;
        }
    }
  }

  /// 格式化时间差 转成时分秒
  ///
  /// 如果参数时间小于当前时间 返回null
  ///
  /// @return xx时xx分xx秒
  String? formatDiff(LDay maxDay, {bool showSecond = true, showMinute = true}) {
    if (isAfter(maxDay)) return null;
    var second = diff(maxDay, DayUnit.second);
    if (second < 0) return null;
    var hour = second ~/ 3600;
    var min = (second - hour * 3600) ~/ 60;
    var sec = second % 60;
    var timeStr = '';
    timeStr += '${hour < 10 ? '0$hour' : hour.toString()}时';
    if (!showMinute) {
      return timeStr;
    }
    timeStr += '${min < 10 ? '0$min' : min.toString()}分';
    if (!showSecond) {
      return timeStr;
    }
    timeStr += '${sec < 10 ? '0$sec' : sec.toString()}秒';
    return timeStr;
  }

  /// 转换为数组
  List<int> toArray() {
    return [
      year,
      month,
      day,
      hour,
      minute,
      second,
      millisecond,
      microsecond,
    ];
  }

  /// 转换为map
  Map<String, int> toMap() {
    return {
      'year': year,
      'month': month,
      'day': day,
      'hour': hour,
      'minute': minute,
      'second': second,
      'millisecond': millisecond,
      'microsecond': microsecond,
    };
  }

  /// 本时间是否在参数时间之前
  bool isBefore(LDay day, [DayUnit unit = DayUnit.microsecond]) {
    return LDay.fromLDay(this).startOf(unit).microUnix <
        LDay.fromLDay(day).startOf(unit).microUnix;
  }

  /// 本时间是否和参数时间相同
  ///
  /// 默认用微秒对比,如果传入第二个参数,则以用unit指定的单位对比
  ///
  /// 例: 传入 月,则按 年和月对比,传入日,则按年和月和日对比
  bool isSame(LDay day, [DayUnit unit = DayUnit.microsecond]) {
    return LDay.fromLDay(this).startOf(unit).microUnix ==
        LDay.fromLDay(day).startOf(unit).microUnix;
  }

  /// 本时间是否在参数时间之后
  bool isAfter(LDay day, [DayUnit unit = DayUnit.microsecond]) {
    return LDay.fromLDay(this).startOf(unit).microUnix >
        LDay.fromLDay(day).startOf(unit).microUnix;
  }

  /// 本时间是否在参数时间之前或相同
  ///
  /// 默认用微秒对比,如果传入第二个参数,则以用unit指定的单位对比
  ///
  /// 例: 传入 月,则按 年和月对比,传入日,则按年和月和日对比
  bool isSameOrBefore(LDay day, [DayUnit unit = DayUnit.microsecond]) {
    return isSame(day, unit) || isBefore(day, unit);
  }

  /// 本时间是否在参数时间之后或相同
  ///
  /// 默认用微秒对比,如果传入第二个参数,则以用unit指定的单位对比
  ///
  /// 例: 传入 月,则按 年和月对比,传入日,则按年和月和日对比
  bool isSameOrAfter(LDay day, [DayUnit unit = DayUnit.microsecond]) {
    return isSame(day, unit) || isAfter(day, unit);
  }

  /// 本时间是否在两个参数时间之内
  ///
  /// 默认用微秒对比,如果传入第三个参数,则以用unit指定的单位对比
  ///
  /// 例: 传入 月,则按 年和月对比,传入日,则按年和月和日对比
  ///
  /// 第四个参数为是否包含边界,如果是,则本时间等于start和end时间也返回true
  bool isBetween(LDay start, LDay end,
      [DayUnit unit = DayUnit.microsecond, bool contain = false]) {
    if (contain == true) {
      return isSameOrBefore(start, unit) && isSameOrAfter(end, unit) ||
          isSameOrAfter(start, unit) && isSameOrBefore(end, unit);
    } else {
      return isBefore(start, unit) && isAfter(end, unit) ||
          isAfter(start, unit) && isBefore(end, unit);
    }
  }

  /// 解析格式化时间的匹配值
  String _processMatchFromFormat(Match m) {
    var mm = m[0];
    switch (mm) {
      case 'Y':
      case 'YY':
        return year.toString().substring(2, year.toString().length);
      case 'YYY':
      case 'YYYY':
        return year.toString();
      case 'YYYYY':
        var y = year.toString();
        var n = '';
        for (var i = 0; i < y.length; i++) {
          n += _dayZh[int.tryParse(y[i]) ?? 0]!;
        }
        return '$n年';
      case 'M':
        return month.toString();
      case 'MM':
        return month.toString().padLeft(2, '0');
      case 'MMM':
        return '${_monthDayZh[month]}';
      case 'D':
        return day.toString();
      case 'DD':
        return day.toString().padLeft(2, '0');
      case 'DDD':
        return '${_dayZh[day]}日';
      case 'H':
        return hour.toString();
      case 'HH':
        return hour.toString().padLeft(2, '0');
      case 'HHH':
        return '${_dayZh[hour]}点';
      case 'h':
        return (hour % 12 == 0 ? 12 : hour % 12).toString();
      case 'hh':
        return (hour % 12 == 0 ? 12 : hour % 12).toString().padLeft(2, '0');
      case 'hhh':
        return '${_dayZh[hour % 12 == 0 ? 12 : hour % 12]}点';
      case 'm':
        return minute.toString();
      case 'mm':
        return minute.toString().padLeft(2, '0');
      case 'mmm':
        return '${_dayZh[minute]}分';
      case 's':
        return second.toString();
      case 'ss':
        return second.toString().padLeft(2, '0');
      case 'sss':
        return '${_dayZh[second]}秒';
      case 'SSS':
        return millisecond.toString().padLeft(3, '0');
      case 'SWS':
        return microsecond.toString().padLeft(3, '0');
      case 'W':
        return _weekDayZh[weekday]!;
    }
    return mm ?? '';
  }

  DateTime _createTime(int year, int month, int day, int hour, int minute,
      int second, int millsecond, int microsecond, bool isUtc) {
    if (isUtc) {
      return DateTime.utc(
          year, month, day, hour, minute, second, millsecond, microsecond);
    } else {
      return DateTime(
          year, month, day, hour, minute, second, millsecond, microsecond);
    }
  }

  /// 解析中文单位的日期
  ///
  /// 例:
  /// - 2021年12月31日 12点12分12秒12毫秒12微秒
  /// - 2021年12月31日 12时12分12秒12毫秒12微秒
  /// - 2021年12月31日 12时12分12秒
  /// - 2021年12月31日12时12分12秒
  /// - 2021年12月31日 12时
  /// - 2021年
  static List<int> _parseCNUnit(String date) {
    List<int> times = [];
    var oStr = date.replaceAll(' ', '');
    if (oStr.contains('年')) {
      times.add(int.parse(oStr.split('年')[0]));
      oStr = oStr.split('年')[1];
    }
    if (oStr.contains('月')) {
      times.add(int.parse(oStr.split('月')[0]));
      oStr = oStr.split('月')[1];
    }
    if (oStr.contains('日')) {
      times.add(int.parse(oStr.split('日')[0]));
      oStr = oStr.split('日')[1];
    }
    if (oStr.contains('点')) {
      times.add(int.parse(oStr.split('点')[0]));
      oStr = oStr.split('点')[1];
    } else if (oStr.contains('时')) {
      times.add(int.parse(oStr.split('时')[0]));
      oStr = oStr.split('时')[1];
    }
    if (oStr.contains('分')) {
      times.add(int.parse(oStr.split('分')[0]));
      oStr = oStr.split('分')[1];
    }
    if (oStr.contains('毫秒')) {
      oStr = oStr.replaceAll('毫秒', 'SS');
    }
    if (oStr.contains('微秒')) {
      oStr = oStr.replaceAll('微秒', 'WS');
    }
    if (oStr.contains('秒')) {
      times.add(int.parse(oStr.split('秒')[0]));
      oStr = oStr.split('秒')[1];
    }
    if (oStr.contains('SS')) {
      times.add(int.parse(oStr.split('SS')[0]));
      oStr = oStr.split('SS')[1];
    }
    if (oStr.contains('WS')) {
      times.add(int.parse(oStr.split('WS')[0]));
    }
    return times;
  }

  /// 解析中文日期
  /// 例:
  /// * 二零二四年三月二十八日 十二点十二分十二秒十二毫秒十二微秒
  /// * 二零二四年三月二十八日 十二时十二分十二秒
  /// * 二零二四年三月二十八日 十二点十二分
  /// * 二零二四年三月二十八日 十二点
  /// * 二零二四年
  /// * 二零二四年三月
  /// * 二零二四年三月二十八日
  static List<int> _parseCN(String date) {
    List<int> times = [];
    var oStr = date.replaceAll(' ', '');
    if (oStr.contains('年')) {
      var yearCNStr = oStr.split('年')[0];
      var yearStr = '';
      for (var i = 0; i < yearCNStr.length; i++) {
        yearStr += _dayZh.values.toList().indexOf(yearCNStr[i]).toString();
      }
      times.add(int.tryParse(yearStr) ?? 0);
      oStr = oStr.split('年')[1];
    }
    if (oStr.contains('月')) {
      var monthCNStr = '${oStr.split('月')[0]}月';
      var monthNum = _monthDayZh.keys
          .toList()[_monthDayZh.values.toList().indexOf(monthCNStr)];
      times.add(monthNum);
      oStr = oStr.split('月')[1];
    }
    if (oStr.contains('日')) {
      var dayCNStr = oStr.split('日')[0];
      var dayNum =
          _dayZh.keys.toList()[_dayZh.values.toList().indexOf(dayCNStr)];
      times.add(dayNum);
      oStr = oStr.split('日')[1];
    }
    if (oStr.contains('点')) {
      var hourCNStr = oStr.split('点')[0];
      var hourNum =
          _dayZh.keys.toList()[_dayZh.values.toList().indexOf(hourCNStr)];
      times.add(hourNum);
      oStr = oStr.split('点')[1];
    } else if (oStr.contains('时')) {
      var hourCNStr = oStr.split('时')[0];
      var hourNum =
          _dayZh.keys.toList()[_dayZh.values.toList().indexOf(hourCNStr)];
      times.add(hourNum);
      oStr = oStr.split('点')[1];
    }
    if (oStr.contains('分')) {
      var minuteCNStr = oStr.split('分')[0];
      var minuteNum =
          _dayZh.keys.toList()[_dayZh.values.toList().indexOf(minuteCNStr)];
      times.add(minuteNum);
      oStr = oStr.split('分')[1];
    }
    if (oStr.contains('毫秒')) {
      oStr = oStr.replaceAll('毫秒', 'SS');
    }
    if (oStr.contains('微秒')) {
      oStr = oStr.replaceAll('微秒', 'WS');
    }
    if (oStr.contains('秒')) {
      var secondCNStr = oStr.split('秒')[0];
      var secondNum =
          _dayZh.keys.toList()[_dayZh.values.toList().indexOf(secondCNStr)];
      times.add(secondNum);
      oStr = oStr.split('秒')[1];
    }
    if (oStr.contains('SS')) {
      var millisecondCNStr = oStr.split('SS')[0];
      var millisecondNum = _dayZh.keys
          .toList()[_dayZh.values.toList().indexOf(millisecondCNStr)];
      times.add(millisecondNum);
      oStr = oStr.split('SS')[1];
    }
    if (oStr.contains('WS')) {
      var millisecondCNStr = oStr.split('WS')[0];
      var millisecondNum = _dayZh.keys
          .toList()[_dayZh.values.toList().indexOf(millisecondCNStr)];
      times.add(millisecondNum);
    }
    return times;
  }

  @override
  String toString() {
    return _date.toString();
  }
}

/// 月类型
enum MonthType {
  /// 按30天计算
  use30,

  /// 按31天计算
  use31,

  /// 按自然月计算
  useNaturalMonth
}

/// 日期单位
enum DayUnit {
  /// 单位：年
  year,

  /// 单位：月
  month,

  /// 单位：日
  day,

  /// 单位：时
  hour,

  /// 单位：分
  minute,

  /// 单位：秒
  second,

  /// 单位：毫秒
  millisecond,

  /// 单位：微秒
  microsecond,
}

const Map<int, String> _weekDayZh = {
  1: '星期一',
  2: '星期二',
  3: '星期三',
  4: '星期四',
  5: '星期五',
  6: '星期六',
  7: '星期天',
};

const Map<int, String> _monthDayZh = {
  1: '一月',
  2: '二月',
  3: '三月',
  4: '四月',
  5: '五月',
  6: '六月',
  7: '七月',
  8: '八月',
  9: '九月',
  10: '十月',
  11: '十一月',
  12: '十二月',
};

const Map<int, String> _dayZh = {
  0: '零',
  1: '一',
  2: '二',
  3: '三',
  4: '四',
  5: '五',
  6: '六',
  7: '七',
  8: '八',
  9: '九',
  10: '十',
  11: '十一',
  12: '十二',
  13: '十三',
  14: '十四',
  15: '十五',
  16: '十六',
  17: '十七',
  18: '十八',
  19: '十九',
  20: '二十',
  21: '二十一',
  22: '二十二',
  23: '二十三',
  24: '二十四',
  25: '二十五',
  26: '二十六',
  27: '二十七',
  28: '二十八',
  29: '二十九',
  30: '三十',
  31: '三十一',
  32: '三十二',
  33: '三十三',
  34: '三十四',
  35: '三十五',
  36: '三十六',
  37: '三十七',
  38: '三十八',
  39: '三十九',
  40: '四十',
  41: '四十一',
  42: '四十二',
  43: '四十三',
  44: '四十四',
  45: '四十五',
  46: '四十六',
  47: '四十七',
  48: '四十八',
  49: '四十九',
  50: '五十',
  51: '五十一',
  52: '五十二',
  53: '五十三',
  54: '五十四',
  55: '五十五',
  56: '五十六',
  57: '五十七',
  58: '五十八',
  59: '五十九',
  60: '六十',
  61: '六十一',
};
